﻿
// MyTetrisView.cpp: CMyTetrisView 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MyTetris.h"
#endif

#include "MyTetrisDoc.h"
#include "MyTetrisView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define BlockInitialX 0
#define BlockInitialY 0
#define RED RGB(255,0,0)
#define GREEN RGB(0,255,0)
#define BLUE RGB(0,0,255)
#define WHITE RGB(255,255,255)
#define BLACK RGB(0,0,0)
#define DARKORANGE RGB(255,140,0)
#define TOMATO RGB(255,99,71)
#define DEEPPINK RGB(255,20,147)
#define FUCHSIA RGB(255,0,255)
#define OLIVE RGB(128,128,0)

#define PanelX   20
#define PanelY   20
#define UNIT 25
#define UNITX 10
#define UNITY 20


// CMyTetrisView

IMPLEMENT_DYNCREATE(CMyTetrisView, CView)

BEGIN_MESSAGE_MAP(CMyTetrisView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
	ON_WM_PAINT()
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	ON_WM_CREATE()
END_MESSAGE_MAP()

// CMyTetrisView 构造/析构

CMyTetrisView::CMyTetrisView() noexcept
{
	// TODO: 在此处添加构造代码
	//flag = 0;
	flag2 = 1;
	flag = 1;
	key = 1;
	Y = 1;
	count = 0;
	IDC_TIMER = 1;
	for (int x = 0; x < UNITX; x++)
	{
		for (int y = 0; y < UNITY; y++)
		{
			cor[x][y] = 0;
		}
	}

	for (int i = 0; i < 4; i++)
	{
		dd[i] = 0;
	}
}

CMyTetrisView::~CMyTetrisView()
{
}

BOOL CMyTetrisView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CMyTetrisView 绘图

void CMyTetrisView::OnDraw(CDC* /*pDC*/)
{
	CMyTetrisDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	//BlockDisplay();
}


// CMyTetrisView 打印

BOOL CMyTetrisView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CMyTetrisView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CMyTetrisView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}


// CMyTetrisView 诊断

#ifdef _DEBUG
void CMyTetrisView::AssertValid() const
{
	CView::AssertValid();
}

void CMyTetrisView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMyTetrisDoc* CMyTetrisView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyTetrisDoc)));
	return (CMyTetrisDoc*)m_pDocument;
}
#endif //_DEBUG


// CMyTetrisView 消息处理程序


void CMyTetrisView::BlockCreate()
{
	// TODO: 在此处添加实现代码.
	for (int i = 0; i < 4; i++)
	{
		m_ptBlockInitial[i].x = 0;
		m_ptBlockInitial[i].y = 0;
	}
	/*for (int i = 0; i < 4; i++)
	{
		m_ptBlockCopy[i].x = 0;
		m_ptBlockCopy[i].y = 0;
	}*/

	index = rand() % 7;
	switch (index)
	{
	case 1:
 		m_ptBlockInitial[0].x = BlockInitialX + 3;
		m_ptBlockInitial[0].y = BlockInitialY + 0 ;
		m_ptBlockInitial[1].x = BlockInitialX + 4;
		m_ptBlockInitial[1].y = BlockInitialY + 0;
		m_ptBlockInitial[2].x = BlockInitialX + 5;
		m_ptBlockInitial[2].y = BlockInitialY + 0;
		m_ptBlockInitial[3].x = BlockInitialX + 6;
		m_ptBlockInitial[3].y = BlockInitialY + 0;
		m_clrBlockInitial = OLIVE;
		break;

	case 2:
		m_ptBlockInitial[0].x = BlockInitialX + 5;
		m_ptBlockInitial[0].y = BlockInitialY + 0;
		m_ptBlockInitial[1].x = BlockInitialX + 6;
		m_ptBlockInitial[1].y = BlockInitialY + 0;
		m_ptBlockInitial[2].x = BlockInitialX + 6;
		m_ptBlockInitial[2].y = BlockInitialY + 1;
		m_ptBlockInitial[3].x = BlockInitialX + 7;
		m_ptBlockInitial[3].y = BlockInitialY + 1;
		m_clrBlockInitial = RED;
		break;

	case 3:
		m_ptBlockInitial[0].x = BlockInitialX + 5;
		m_ptBlockInitial[0].y = BlockInitialY + 1;
		m_ptBlockInitial[1].x = BlockInitialX + 6;
		m_ptBlockInitial[1].y = BlockInitialY + 1;
		m_ptBlockInitial[2].x = BlockInitialX + 6;
		m_ptBlockInitial[2].y = BlockInitialY + 0;
		m_ptBlockInitial[3].x = BlockInitialX + 7;
		m_ptBlockInitial[3].y = BlockInitialY + 0;
		m_clrBlockInitial = GREEN;
		break;

	case 4:
		m_ptBlockInitial[0].x = BlockInitialX + 5;
		m_ptBlockInitial[0].y = BlockInitialY + 0;
		m_ptBlockInitial[1].x = BlockInitialX + 6;
		m_ptBlockInitial[1].y = BlockInitialY + 0;
		m_ptBlockInitial[2].x = BlockInitialX + 7;
		m_ptBlockInitial[2].y = BlockInitialY + 0;
		m_ptBlockInitial[3].x = BlockInitialX + 7;
		m_ptBlockInitial[3].y = BlockInitialY + 1;
		m_clrBlockInitial = BLUE;
		break;

	case 5:
		m_ptBlockInitial[0].x = BlockInitialX + 5;
		m_ptBlockInitial[0].y = BlockInitialY + 1;
		m_ptBlockInitial[1].x = BlockInitialX + 6;
		m_ptBlockInitial[1].y = BlockInitialY + 1;
		m_ptBlockInitial[2].x = BlockInitialX + 7;
		m_ptBlockInitial[2].y = BlockInitialY + 1;
		m_ptBlockInitial[3].x = BlockInitialX + 7;
		m_ptBlockInitial[3].y = BlockInitialY + 0;
		m_clrBlockInitial = DARKORANGE;
		break;

	case 6:
		m_ptBlockInitial[0].x = BlockInitialX + 5;
		m_ptBlockInitial[0].y = BlockInitialY + 0;
		m_ptBlockInitial[1].x = BlockInitialX + 5;
		m_ptBlockInitial[1].y = BlockInitialY + 1;
		m_ptBlockInitial[2].x = BlockInitialX + 6;
		m_ptBlockInitial[2].y = BlockInitialY + 1;
		m_ptBlockInitial[3].x = BlockInitialX + 4;
		m_ptBlockInitial[3].y = BlockInitialY + 1;
		m_clrBlockInitial = DEEPPINK;
		break;

	case 0:
		m_ptBlockInitial[0].x = BlockInitialX + 5;
		m_ptBlockInitial[0].y = BlockInitialY + 0;
		m_ptBlockInitial[1].x = BlockInitialX + 6;
		m_ptBlockInitial[1].y = BlockInitialY + 0;
		m_ptBlockInitial[2].x = BlockInitialX + 5;
		m_ptBlockInitial[2].y = BlockInitialY + 1;
		m_ptBlockInitial[3].x = BlockInitialX + 6;
		m_ptBlockInitial[3].y = BlockInitialY + 1;
		m_clrBlockInitial = FUCHSIA;
		break;
	}
	for (int a = 0; a < 4; a++)
	{
		m_ptBlockCopy[a].x = m_ptBlockInitial[a].x;
		m_ptBlockCopy[a].y = m_ptBlockInitial[a].y;
	}
}


void CMyTetrisView::BlockDisplay()
{
	// TODO: 在此处添加实现代码.
	CPaintDC dc(this);
	CString str1("游戏说明");
	CString str2("向左,右,下方向的按键控制移动");
	CString str3("空格键控制旋转");
	CString str4("单击设置按钮可以选择游戏等级");
	CString str5("单击开始按钮可以开始新游戏");
	CString str6("单击退出按钮关闭游戏窗口");
	CString str7("游戏说明");
	CString str8("|");
	CString str9("|");
	CString str10("|");
	CString str11("|");
	CString str12("|");
	CString str13("|");
	CString str14("|");
	dc.TextOut(PanelX + UNITX * UNIT + 100, PanelY + 80, str1);
	dc.TextOut(PanelX + UNITX * UNIT + 100, PanelY + 130, str2);
	dc.TextOut(PanelX + UNITX * UNIT + 100, PanelY + 180, str3);
	dc.TextOut(PanelX + UNITX * UNIT + 100, PanelY + 230, str4);
	dc.TextOut(PanelX + UNITX * UNIT + 100, PanelY + 280, str5);
	dc.TextOut(PanelX + UNITX * UNIT + 100, PanelY + 330, str6);
	dc.TextOut(PanelX + UNITX * UNIT + 100, PanelY + 380, str7);
	dc.TextOut(PanelX + UNITX * UNIT + 350, PanelY + 80, str8);
	dc.TextOut(PanelX + UNITX * UNIT + 350, PanelY + 130, str9);
	dc.TextOut(PanelX + UNITX * UNIT + 350, PanelY + 180, str10);
	dc.TextOut(PanelX + UNITX * UNIT + 350, PanelY + 230, str11);
	dc.TextOut(PanelX + UNITX * UNIT + 350, PanelY + 280, str12);
	dc.TextOut(PanelX + UNITX * UNIT + 350, PanelY + 330, str13);
	dc.TextOut(PanelX + UNITX * UNIT + 350, PanelY + 380, str14);

	//消除运动轨迹
	for (int a = 0; a < 4; a++)
	{
		dc.FillSolidRect(PanelX + dd[a].x * UNIT, PanelY + dd[a].y * UNIT, UNIT - 1, UNIT - 1, BLACK);
	}

	//显示移动方块
	for (int a = 0; a < 4; a++)
	{
			dc.FillSolidRect(PanelX + m_ptBlockInitial[a].x * UNIT, PanelY + m_ptBlockInitial[a].y * UNIT,
				UNIT - 1, UNIT - 1, m_clrBlockInitial);
	}

	//每次方块落地重绘
	if (flag2)
	{
		//擦除右上角上一次图形
		CBrush brush;
		CRect rect(PanelX + UNITX * UNIT + 70, PanelY, PanelX + UNITX * UNIT + 300, PanelY + 2 * UNIT);
		brush.CreateSolidBrush(WHITE);
		CBrush *pOldBrush = dc.SelectObject(&brush);
		dc.FillRect(rect, &brush);
		dc.SelectObject(pOldBrush);

		//右上角显示即将下落的图形
		for (int a = 0; a < 4; a++)
		{
			dc.FillSolidRect(PanelX + 250 + m_ptBlockCopy[a].x * UNIT, PanelY + m_ptBlockCopy[a].y * UNIT,
				UNIT - 1, UNIT - 1, m_clrBlockInitial);
		}

		//绘制黑色背景
		for (int x = 0; x < UNITX; x++)
		{
			for (int y = 0; y < UNITY; y++)
			{
				dc.FillSolidRect(PanelX + x * UNIT, PanelY + y * UNIT, UNIT - 1, UNIT - 1, BLACK);
			}
			//dc.FillSolidRect(PanelX + 250, PanelY, 150, 150, WHITE);
		}

		//绘制底部方块群
		for (int x = 0; x < UNITX; x++)
		{
			for (int y = 0; y < UNITY; y++)
			{
				if (2 == cor[x][y])
				{
					dc.FillSolidRect(PanelX + x * UNIT, PanelY + y * UNIT, UNIT - 1, UNIT - 1, color[x][y]);
				}
			}
		}

		//方块到底后立即显示新方块
		if (flag)
		{
			for (int a = 0; a < 4; a++)
			{
				dc.FillSolidRect(PanelX + m_ptBlockInitial[a].x * UNIT, PanelY + m_ptBlockInitial[a].y * UNIT,
					UNIT - 1, UNIT - 1, m_clrBlockInitial);
			}
			flag = 0;
		}
		flag2 = 0;
	}
}


void CMyTetrisView::OnPaint()
{
	BlockDisplay();
}


void CMyTetrisView::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	Y = 1;
	if (key)
	{
		if (ArriveAtBottom())
		{
			BlockErase();
			MoveToBottom();
			key = 1;
		}
		else
		{			
			GameOver();
			BlockCreate();
			key = 1;
			flag = 1;
		}
	}
	Y = 0;
	Invalidate(FALSE);
	UpdateWindow();
	CView::OnTimer(nIDEvent);
}


void CMyTetrisView::MoveToLeft()
{
	// TODO: 在此处添加实现代码.
	for (int a = 0; a < 4; a++)
	{
		m_ptBlockInitial[a].x--;
	}
}


void CMyTetrisView::MoveToRight()
{
	// TODO: 在此处添加实现代码.
	for (int a = 0; a < 4; a++)
	{
		m_ptBlockInitial[a].x++;
	}
}


void CMyTetrisView::MoveToBottom()
{
	// TODO: 在此处添加实现代码.
	for (int a = 0; a < 4; a++)
	{
		m_ptBlockInitial[a].y++;
	}
}




void CMyTetrisView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (!Y)
	{
		key = 0;
		switch (nChar)
		{
		case VK_LEFT:
			if (!OutOfLeft())
			{
				BlockErase();
				MoveToLeft();
			}
			break;
		case VK_RIGHT:
			if (!OutOfRight())
			{
				BlockErase();
				MoveToRight();
			}
			break;
		case VK_DOWN:
			if (ArriveAtBottom())
			{
				BlockErase();
				MoveToBottom();
			}
			else
			{
				GameOver();
				BlockCreate();
				flag = 1;
			}
			break;
		case VK_SPACE:
			BlockErase();
			MoveToRotate();
			break;
		}
		key = 1;
	}
	Invalidate(FALSE);
	UpdateWindow();
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


void CMyTetrisView::BlockErase()
{
	// TODO: 在此处添加实现代码.
	for (int a = 0; a < 4; a++)
	{
		//cor[m_ptBlockInitial[a].x][m_ptBlockInitial[a].y] = 0;
		dd[a].x = m_ptBlockInitial[a].x;
		dd[a].y = m_ptBlockInitial[a].y;
	}
}


int CMyTetrisView::OutOfLeft()
{
	// TODO: 在此处添加实现代码.
	for (int a = 0; a < 4; a++)
	{
		if ((m_ptBlockInitial[a].x <= 0) || (cor[m_ptBlockInitial[a].x - 1][m_ptBlockInitial[a].y] == 2))
		{
			return 1;
		}	
	}
	return 0;
}


int CMyTetrisView::OutOfRight()
{
	// TODO: 在此处添加实现代码.
	for (int a = 0; a < 4; a++)
	{
		if ((m_ptBlockInitial[a].x >= 9) || (cor[m_ptBlockInitial[a].x + 1][m_ptBlockInitial[a].y]) == 2)
			return 1;
	}
	return 0;
}


int CMyTetrisView::MoveToRotate()
{
	// TODO: 在此处添加实现代码.
	CPoint m_ptNewOrigin;
	CPoint m_ptNew;
	CPoint bb[4];
	int h;
	for (int a = 0; a < 4; a++)
	{
		bb[a].x = m_ptBlockInitial[a].x;
		bb[a].y = m_ptBlockInitial[a].y;
	}
	switch (index)
	{
	case 1:
		m_ptNewOrigin.x = m_ptBlockInitial[2].x;
		m_ptNewOrigin.y = m_ptBlockInitial[2].y;
		h = 2;
		break;
	case 0:
		return 0;
	default:
		m_ptNewOrigin.x = m_ptBlockInitial[1].x;
		m_ptNewOrigin.y = m_ptBlockInitial[1].y;
		h = 1;
		break;
	}
	for (int a = 0; a < 4; a++)
	{
		if (a != h)
		{
			m_ptNew.x = (m_ptBlockInitial[a].x - m_ptNewOrigin.x);
			m_ptNew.y = (m_ptBlockInitial[a].y - m_ptNewOrigin.y);

			m_ptBlockInitial[a].x = -m_ptNew.y + m_ptNewOrigin.x;
			m_ptBlockInitial[a].y = m_ptNew.x + m_ptNewOrigin.y;
			if ((cor[m_ptBlockInitial[a].x][m_ptBlockInitial[a].y] == 2) ||
				(m_ptBlockInitial[a].x > 9) || (m_ptBlockInitial[a].x < 0) ||
				(m_ptBlockInitial[a].y > 19) || (m_ptBlockInitial[a].y < 0))
			{
				for (int d = 0; d < 4; d++)
				{
					m_ptBlockInitial[d].x = bb[d].x;
					m_ptBlockInitial[d].y = bb[d].y;
				}
				return 0;
			}
		}
	}
	return 1;
}


int CMyTetrisView::ArriveAtBottom()                   //到底返回0,没到底返回1
{
	// TODO: 在此处添加实现代码.
	for (int a = 0; a < 4; a++)
	{
		if ((UNITY-1) == m_ptBlockInitial[a].y)
		{
			for (int c = 0; c < 4; c++)
			{
				cor[m_ptBlockInitial[c].x][m_ptBlockInitial[c].y] = 2;
				color[m_ptBlockInitial[c].x][m_ptBlockInitial[c].y] = m_clrBlockInitial;
				flag2 = 1;
				flag = 1;
			}
			return 0;
		}
		if (2 == cor[m_ptBlockInitial[a].x][m_ptBlockInitial[a].y + 1])
		{
			for (int c = 0; c < 4; c++)
			{
				cor[m_ptBlockInitial[c].x][m_ptBlockInitial[c].y] = 2;
				color[m_ptBlockInitial[c].x][m_ptBlockInitial[c].y] = m_clrBlockInitial;
				flag2 = 1;
				flag = 1;
			}
			return 0;
		}
	}
	return 1;

}


void CMyTetrisView::GameOver()
{
	// TODO: 在此处添加实现代码.
	int flagover ;
	for (int a = UNITY - 1; a >= 0; a--)
	{
		flagover = 0;
		for (int b = 0; b < UNITX; b++)
		{
			if (2 == cor[b][a])
			{
				flagover++;
			}
			if (10 == flagover)
			{
				count += 100;
				for (int c = 0; c < UNITX; c++)
				{
					cor[c][a] = 0;
					color[c][a] = OLIVE;
				}
				for (int t = a; t > 0; t--)
				{
					for (int d = 0; d < UNITX; d++)
					{
						if (2 == cor[d][t - 1])
						{
							cor[d][t] = cor[d][t-1];
							color[d][t] = color[d][t-1];
							cor[d][t - 1] = 0;
							color[d][t - 1] = OLIVE;
						}
					}
				}
				a = a + 1;
			}
		}
	}
	for (int a = 0; a < UNITX - 1; a++)
	{
		if (2 == cor[a][0])
		{
			KillTimer(IDC_TIMER);
			CString str;
			int select;
			str.Format(_T("您的得分: %d,  点击 ''是'' 重新开始,否则退出"), count);
			select = MessageBox(str, L"MyTeris",MB_YESNO);
			if (7 == select)
				exit(0);
			count = 0;
			for (int i = 0; i < UNITX; i++)
			{
				for (int j = 0; j < UNITY; j++)
				{
					cor[i][j] = 0;
					flag2 = 1;
				}
			}
			SetTimer(IDC_TIMER, 500, NULL);
		}
	}
}

int CMyTetrisView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	BlockCreate();
	SetTimer(IDC_TIMER, 500, NULL);
	return 0;
}
